gusucode.com > VC++ RingSDK界面库 > VC++ RingSDK界面库/code/libsrc/ringlib/file.cpp
/********************************************************************** // // // ########## ###### ######### # ###### # // ############# ########### ######### ######### ### // ######## # ### ## ############# ## ## ##### # #### // #### ## ## ### ### ### # # ##### ##### // # ### # # ## ## ## ## ### // ## ###### ## ## #### #### # # ## // ######### ### ## ### ####### ###### ## ## ### // ###### ## ###### ## ## #### # ## #### // ####### ## ###### ## ### ## ## ### ###### // ######### ## ###### ## ###### ### ## ### # ##### // ## ###### ####### ### #### ## ## ####### ######## ## #### // ## #### ### # ### ### ## ########## ###### ## #### // ## ## ## ######### #### # ## // # ### // ## // ### // ## // // // RingSDK类库 ringlib.lib //作者:临风 // //版本:1.0 // //声明:本类库可以自由使用而不须对作者作出任何回报,但作者希望能得到 // 你的鼓励和支持。你可以对类库源码作出修改和改进,但希望你能在 // 修改的同时给作者一份同样的副本。 // 本类库不得用于任何商业用途,如确实需要,请与作者联系。 // // 在此感谢YZFree对代码做了大量的编写及修正工作,然后我又做了一些 // 修正,所以已经分不清哪些代码是谁写的了:-P // //e-mail:ringphone@sina.com // //原文件名:file.cpp // //说明:文件操作类实现代码 // **********************************************************************/ #define MAKE_SELF_LIB #include "ringlib.h" #include <shlobj.h> //因为Win2000以前的windows该结构不一样,因此这里统一起来,使这些版本的尺寸一致 typedef struct tagRingOFN { OPENFILENAME m_ofn; #if(_WIN32_WINNT < 0x0500) void * pvReserved; DWORD dwReserved; DWORD FlagsEx; #endif }RINGOPENFILENAME, *LPRINGOPENFILENAME; ringFile::ringFile() { Init(); } ringFile::ringFile(LPCTSTR szFilename) { Init(); SetFile(szFilename); } ringFile::~ringFile() { Destroy(); } // 初始化类内部成员变量 void ringFile::Init() { memset(m_szFilename,0,MAX_PATH); memset(m_szDrive,0,4); m_lpszPath = NULL; m_lpszFilename = NULL; m_lpszTitlename = NULL; m_lpszExtname = NULL; m_hFile = NULL; m_dwRWNum = 0UL; m_bufSize = 0; m_lpFilebuf = NULL; m_dwFileAttr = 0xffffffff; m_dwFileSize = 0; m_bExtern = FALSE; m_aAttrib = RFA_VOID; } void ringFile::SetFile(HANDLE hFile) { Close(); ClearFileName(); m_hFile = hFile; m_bExtern = TRUE; m_aAttrib = RFA_FILE; BY_HANDLE_FILE_INFORMATION bhfi; ::GetFileInformationByHandle(hFile, &bhfi); m_dwFileAttr = bhfi.dwFileAttributes; m_dwFileSize = bhfi.nFileSizeLow; } ///////////////////////////////////////////////////////////////////////////////////////// // //设定文件名,并转换为绝对路径 // void ringFile::SetFile(LPCTSTR format, ...) { va_list ap; TCHAR szTemp[MAX_PATH],tmp[MAX_PATH]; // 如果以前存在已打开的文件,则关闭它 Close(); ClearFileName(); // 合成路径 if(format) { va_start(ap, format); _vsntprintf((char*)szTemp,MAX_PATH-2,format,ap); //vsprintf((char*)szTemp,format,ap); va_end(ap); } //记录当前路径 memset(tmp,0,MAX_PATH); GetCurrentDirectory(MAX_PATH,tmp); //设置当前路径为程序路径 ringStr str(RSTR_CURRPATH); SetCurrentDirectory(str.string()); // 转换为绝对路径 if(!GetFullPathName(szTemp,MAX_PATH,m_szFilename,(LPSTR*)&m_lpszFilename)) { *m_szFilename = '\0'; SetCurrentDirectory(tmp); return; } //还原当前路径 SetCurrentDirectory(tmp); m_aAttrib = check(); } ///////////////////////////////////////////////////////////////////////////////////////// // //只设置文件名,SetFile调用结果m_szFilename可能与输入参数不一致,本函数不改变, //调用结束后m_szFilename可能与输入参数完全一致 // void ringFile::SetFileName(LPCTSTR szFile) { Close(); ClearFileName(); // 复制新的文件名串 if(szFile) { strncpy(m_szFilename,szFile,MAX_PATH); m_aAttrib = check(); //提取文件名位置 m_lpszFilename = m_szFilename + strlen(m_szFilename); if(m_aAttrib != RFA_PATH) { m_lpszFilename --; while(m_lpszFilename != m_szFilename) if(*m_lpszFilename == '\\' || *m_lpszFilename == ':') { m_lpszFilename ++; return; } else m_lpszFilename --; } } } ///////////////////////////////////////////////////////////////////////////////////////// // //通过文件对话框选取文件 // //入口: // szFileType - 过滤串 // szTitle - 对话框标题串 // bSave - ‘打开’/‘另存为’对话框选择标签 // hWnd - 对话框父窗口 // hookproc - 对话框钩子函数 // //返回: // TRUE - 关联成功、FALSE - 失败 // /////////////////////////////////////////////////////////////////////////////////////// int ringFile::Select(LPCTSTR szFileType,LPCTSTR szTitle,BOOL bSave/*=FALSE*/, HWND hWnd/*=m_hWnd*/,LPCTSTR dlgEx/*=NULL*/,LPOFNHOOKPROC hookproc/*=NULL*/, LONG lCustData/*=0*/) { RINGOPENFILENAME ofnTemp; DWORD Errval; TCHAR d[MAX_PATH],f[MAX_PATH],*p,*v; memset(d,0,MAX_PATH); if(szTitle == NULL) szTitle = LANSTR_FILEOPEN; // 规格化过滤串 int len = MAX_PATH * sizeof(TCHAR); int n0cnt = 0; p = (LPTSTR)szFileType; v = f; memset(f,0,len); for(int i=0;i<len;i++) { if(*p == '|' || *p == '\0') { *v++ = '\0'; p++; n0cnt ++; if(n0cnt > 1) break; } else { *v++ = *p++; n0cnt = 0; } } #if(_WIN32_WINNT < 0x0500) n0cnt = 0; #else n0cnt = 12; #endif if(OSType() < OST_WIN2KPRO) ofnTemp.m_ofn.lStructSize = sizeof( OPENFILENAME ) - n0cnt; else ofnTemp.m_ofn.lStructSize = sizeof(RINGOPENFILENAME); ofnTemp.m_ofn.hwndOwner = hWnd; ofnTemp.m_ofn.hInstance = GetInstance(); ofnTemp.m_ofn.lpstrFilter = f; ofnTemp.m_ofn.lpstrCustomFilter = NULL; ofnTemp.m_ofn.nMaxCustFilter = 0; ofnTemp.m_ofn.nFilterIndex = 1; ofnTemp.m_ofn.lpstrFile = d; ofnTemp.m_ofn.nMaxFile = MAX_PATH; ofnTemp.m_ofn.lpstrFileTitle = NULL; ofnTemp.m_ofn.nMaxFileTitle = NULL; ofnTemp.m_ofn.lpstrInitialDir = NULL;//GetSpecPath(RFSP_CURRPATH); ofnTemp.m_ofn.lpstrTitle = szTitle; if(dlgEx && hookproc) ofnTemp.m_ofn.Flags = OFN_ENABLEHOOK | OFN_EXPLORER |OFN_ENABLETEMPLATE|OFN_ENABLESIZING; else ofnTemp.m_ofn.Flags = OFN_EXPLORER; ofnTemp.m_ofn.nFileOffset = NULL; ofnTemp.m_ofn.nFileExtension = 0; ofnTemp.m_ofn.lpstrDefExt = "*"; ofnTemp.m_ofn.lCustData = lCustData; ofnTemp.m_ofn.lpfnHook = hookproc; ofnTemp.m_ofn.lpTemplateName = dlgEx; ofnTemp.FlagsEx = 0; if(!bSave) bSave = GetOpenFileName((LPOPENFILENAME)&ofnTemp); else bSave = GetSaveFileName((LPOPENFILENAME)&ofnTemp); if(!bSave) { Errval = CommDlgExtendedError(); if(Errval != 0) { memset(f,0,len); if(GetErrMessage(Errval,f,MAX_PATH)) Errmsg(f); } return FALSE; } SetFile(d); return TRUE; } ///////////////////////////////////////////////////////////////////////////////////////// // //创建/打开文件 // //特性:文件不存在--创建,文件存在--打开文件并把属性设为NORMAL,即可以写只读文件。关闭 // 文件时恢复文件原属性。根据参数dwCreate: // = RF_NEW -- 清除文件,截断为0 // = RF_APPEND -- 文件指针移到文件尾 // = RF_EDIT -- 打开文件 // //返回:文件不存在--FALSE,成功--TRUE // BOOL ringFile::Create(DWORD dwCreate,DWORD dwAttr/*=FILE_ATTRIBUTE_NORMAL*/) { DWORD dwMode = RF_EDIT; if(m_hFile) { if(dwCreate == RF_APPEND) Seek(0,FILE_END); else if(dwCreate == RF_NEW) Seek(0); return TRUE; } switch(m_aAttrib) { case RFA_FILE: //临时文件无须设置属性 if((m_dwFileAttr & FILE_ATTRIBUTE_TEMPORARY) != FILE_ATTRIBUTE_TEMPORARY) SetFileAttributes(m_szFilename,FILE_ATTRIBUTE_NORMAL); if(dwCreate == RF_NEW) dwMode = TRUNCATE_EXISTING; break; case RFA_NOTEXIST: MkDir(Pathname()); m_dwFileAttr = dwAttr; break; default: return FALSE; } m_hFile = CreateFile(m_szFilename,GENERIC_READ | GENERIC_WRITE,FILE_SHARE_READ | FILE_SHARE_WRITE,NULL,dwMode,FILE_ATTRIBUTE_NORMAL,NULL); if(m_hFile==INVALID_HANDLE_VALUE) { m_hFile = NULL; m_dwFileAttr = 0xffffffff; m_aAttrib = RFA_NOTEXIST; return FALSE; } else { if(dwCreate == RF_APPEND) SeekToEnd(); m_dwFileSize = ::GetFileSize(m_hFile,NULL); return TRUE; } } BOOL ringFile::Create(LPCTSTR lpFilename,DWORD dwCreate) { SetFile(lpFilename); return Create(dwCreate); } BOOL ringFile::CreateTemp(LPCTSTR prefix) { char path[MAX_PATH]; char name[MAX_PATH]; char pfix[4]; // 合成前缀串 if(prefix) { memcpy((void*)pfix,(const void *)prefix, 3); pfix[3] = '\0'; } else wsprintf(pfix,"RFT\0"); // 获得临时文件全路径 GetTempPath(MAX_PATH,path); GetTempFileName((LPCSTR)path,(LPCSTR)pfix,0,(LPSTR)name); if (strlen((char*)name) == 0) return FALSE; // 进行预关联 SetFile((LPCTSTR)name); // 进行实关联 return Create(RF_NEW,FILE_ATTRIBUTE_TEMPORARY); } //////////////////////////////////////////////// // //打开文件 // //返回: // 文件不存在--FALSE,成功--TRUE // BOOL ringFile::Open(DWORD dwAction,DWORD dwShare,DWORD dwAttr) { if(m_hFile) { Seek(0); return TRUE; } m_hFile = CreateFile(m_szFilename,dwAction,dwShare,NULL,OPEN_EXISTING,dwAttr,NULL); if(m_hFile == INVALID_HANDLE_VALUE) { m_hFile = NULL; return FALSE; } else { m_dwFileAttr = GetFileAttributes(m_szFilename); m_dwFileSize = ::GetFileSize(m_hFile,NULL); return TRUE; } } //////////////////////////////////////////////// // //打开文件(包括预关联操作) // //返回: // 文件不存在--FALSE,成功--TRUE // BOOL ringFile::Open(LPCTSTR lpFilename, DWORD dwAction, DWORD dwShare,DWORD dwAttr) { // 预关联 SetFile(lpFilename); return Open(dwAction, dwShare,dwAttr); } //////////////////////////////////////////////// // //关闭文件 // void ringFile::Close() { if(m_hFile) { if(m_bExtern) m_hFile = NULL; // 导入型的关联不负责关闭文件 else { CloseHandle(m_hFile); m_hFile=NULL; // 恢复属性 if(m_dwFileAttr != GetFileAttributes(m_szFilename)) SetFileAttributes(m_szFilename,m_dwFileAttr); } m_bExtern = FALSE; } } void ringFile::ClearFileName() { memset(m_szFilename,0,MAX_PATH); if(m_lpszPath) memset((LPSTR)m_lpszPath,0,MAX_PATH); m_lpszFilename = NULL; if(m_lpszTitlename) memset((LPSTR)m_lpszTitlename,0,MAX_PATH); m_lpszExtname = NULL; memset(m_szDrive,0,4); m_dwFileAttr = 0xffffffff; m_dwFileSize = 0; m_aAttrib = RFA_VOID; if(m_lpFilebuf) memset(m_lpFilebuf,0,m_bufSize); } // 解关联 void ringFile::Destroy() { Close(); memset(m_szFilename,0,MAX_PATH); if(m_lpszPath) m_lpszPath = (LPTSTR)Del(m_lpszPath); m_lpszFilename = NULL; if(m_lpszTitlename) m_lpszTitlename = (LPTSTR)Del(m_lpszTitlename); m_lpszExtname = NULL; memset(m_szDrive,0,4); m_dwFileAttr = 0xffffffff; m_dwFileSize = 0; m_aAttrib = RFA_VOID; if(m_lpFilebuf) m_lpFilebuf = Del(m_lpFilebuf); m_bufSize = 0; } ///////////////////////////////////////////////////////////////////////////////////////// // BOOL ringFile::Read(LPVOID lpBuf,DWORD dwNum,BOOL bCheckReadNum,LPDWORD lpTrueReadNum) { if(lpBuf) { try { memset(lpBuf,0,dwNum); } catch(...) { return FALSE; } } if(ReadFile(m_hFile,lpBuf,dwNum,&m_dwRWNum,NULL)) { if(lpTrueReadNum) *lpTrueReadNum = m_dwRWNum; if(m_dwRWNum == 0 || (bCheckReadNum && (dwNum != m_dwRWNum))) return FALSE; else return TRUE; } else { m_dwRWNum = 0UL; if (lpTrueReadNum) *lpTrueReadNum = 0UL; return FALSE; } } //读取一行,文件结束返回-1,行超长(>dwNum)返回-2,其他返回-3 int ringFile::ReadLine(LPVOID lpBuf,DWORD dwNum) { if(lpBuf) { try { memset(lpBuf,0,dwNum); char szline[1024]; memset(szline,0,1024); int len = -1,pos = GetRWLocation(); DWORD num; if(Read(szline,1023,FALSE,&num)) { for(int i=0;i<1023;i++) { if(szline[i] == '\r') { if(szline[i+1] == '\n') pos += 2; else pos ++; szline[i] = '\0'; len = i; break; } else if(szline[i] == '\n') { pos ++; szline[i] = '\0'; len = i; break; } } if(len == -1 && num == 1023) return RFE_LINEOVERFLOW; else len = strlen(szline); if(dwNum > (DWORD)len) { memcpy(lpBuf,szline,len); Seek(pos + len); return len; } } else return RFE_EOF; } catch(...) { } } return RFE_ERROR; } int ringFile::ReadAll(char **ppbuf) { if(m_dwFileSize > RF_READALL_SIZE) return RFE_FILETOOBIG; //文件超过预定全读尺寸,放弃 // 初始化返回数据 if(ppbuf != 0) *ppbuf = NULL; m_dwRWNum = 0UL; // 申请缓冲区 char *lpbuf; if(m_lpFilebuf && m_dwFileSize > m_bufSize) lpbuf = (char*)New(m_dwFileSize + 10); else if(m_lpFilebuf == NULL) { m_lpFilebuf = (char*)New(m_dwFileSize + 10); lpbuf = (char*)m_lpFilebuf; m_bufSize = m_dwFileSize + 10; } else { lpbuf = (char*)m_lpFilebuf; memset(lpbuf,0,m_bufSize); } if(lpbuf == NULL) return RFE_MEMERROR; DWORD trn; DWORD pos; // 保留读写位置 pos = GetRWLocation(); SeekToBegin(); // 读入所有文件内容 if(!ReadFile(m_hFile,lpbuf,m_dwFileSize,&trn,NULL)) { if(lpbuf != m_lpFilebuf) Del(lpbuf); return RFE_ERROR; } Seek(pos); if(trn != m_dwFileSize) { if(lpbuf != m_lpFilebuf) Del(lpbuf); return RFE_ERROR; } // 返回数据 if(lpbuf != m_lpFilebuf) { if(m_lpFilebuf) Del(m_lpFilebuf); m_lpFilebuf = (LPVOID)lpbuf; m_bufSize = m_dwFileSize; } if(ppbuf) { *ppbuf = (char*)New(m_dwFileSize + 10); memcpy(*ppbuf,lpbuf,m_dwFileSize); } m_dwRWNum = m_dwFileSize; return m_dwFileSize; } BOOL ringFile::Write(const LPVOID lpBuf,DWORD dwNum,BOOL bCheckWriteNum,LPDWORD lpTrueWriteNum) { if(WriteFile(m_hFile,lpBuf,dwNum,&m_dwRWNum,NULL)) { if (lpTrueWriteNum) *lpTrueWriteNum = m_dwRWNum; // 更新文件尺寸 if(GetRWLocation() > m_dwFileSize) m_dwFileSize = GetRWLocation(); if(m_dwRWNum == 0 || (bCheckWriteNum && (dwNum != m_dwRWNum))) return FALSE; else return TRUE; } else { m_dwRWNum = 0UL; if (lpTrueWriteNum) *lpTrueWriteNum = 0UL; return FALSE; } } void ringFile::Flush() { ::FlushFileBuffers(m_hFile); } void ringFile::LockRWArea(DWORD dwPos,DWORD dwCount) { ::LockFile(m_hFile,dwPos,0,dwCount,0); } void ringFile::UnlockRWArea(DWORD dwPos, DWORD dwCount) { ::UnlockFile(m_hFile,dwPos,0,dwCount,0); } DWORD ringFile::Seek(LONG lDistance,DWORD dwMethod) const { return ::SetFilePointer(m_hFile,lDistance,NULL,dwMethod); } DWORD ringFile::SeekToBegin() const { return ::SetFilePointer(m_hFile,0,NULL,FILE_BEGIN); } DWORD ringFile::SeekToEnd() const { return ::SetFilePointer(m_hFile,0,NULL,FILE_END); } DWORD ringFile::GetRWLocation() const { return ::SetFilePointer(m_hFile,0,NULL,FILE_CURRENT); } BOOL ringFile::SetEndOfFile(int pos/*=-1*/) { if(pos != -1) Seek(pos); if(m_hFile && ::SetEndOfFile(m_hFile)) { m_dwFileSize = GetRWLocation(); return TRUE; } else return FALSE; } ///////////////////////////////////////////////////////////////////////////////////////// // //设置文件长度(字节单位) // void ringFile::SetSize(DWORD dwNewLen) { if(m_hFile == NULL) Create(); Seek(dwNewLen,FILE_BEGIN); SetEndOfFile(); } ///////////////////////////////////////////////////////////////////////////////////////// // //获取文件长度(字节单位) // DWORD ringFile::Size() { check(); if(m_hFile != NULL) m_dwFileSize = GetFileSize(m_hFile,NULL); else { Open(); m_dwFileSize = GetFileSize(m_hFile,NULL); Close(); } if(m_dwFileSize == 0xffffffff) //GetFileSize函数失败 m_dwFileSize = 0; return m_dwFileSize; } LPCTSTR ringFile::Fullname() const { return (LPCTSTR)m_szFilename; } LPCTSTR ringFile::Filename() const { return (LPCTSTR)m_lpszFilename; } LPCTSTR ringFile::Extname() const { if(m_lpszExtname == NULL) if(m_lpszFilename) { LPSTR p = (LPSTR)m_lpszFilename + strlen(m_lpszFilename) - 1; LPTSTR v = p + 1; while(p != m_lpszFilename) { if(*p == '.') { (LPSTR)m_lpszExtname = p + 1; return m_lpszExtname; } p --; } (LPSTR)m_lpszExtname = (v - m_szFilename)<MAX_PATH?v:NULL; } return (LPCTSTR)m_lpszExtname; } LPCTSTR ringFile::Pathname() const { if(m_lpszPath == NULL) (LPTSTR)m_lpszPath = (LPTSTR)New(MAX_PATH); if(m_lpszPath && m_lpszPath[0] == '\0' && m_lpszFilename) strncpy((LPSTR)m_lpszPath,m_szFilename,(m_lpszFilename - m_szFilename - 1)); return (LPCTSTR)m_lpszPath; } LPCTSTR ringFile::Drivename() const { if(m_szFilename[1] == ':') memcpy((LPSTR)m_szDrive,m_szFilename,2); return (LPCTSTR)m_szDrive; } LPCTSTR ringFile::Titlename() const { if(m_lpszTitlename == NULL) (LPTSTR)m_lpszTitlename = (LPTSTR)New(MAX_PATH); if(m_lpszTitlename && m_lpszTitlename[0] == '\0' && m_lpszFilename) { LPTSTR p = (LPTSTR)m_lpszFilename + strlen(m_lpszFilename) - 1; //LPTSTR v = p + 1; while(p != m_lpszFilename) { if(*p == '.') { //顺便置一下扩展名 (LPSTR)m_lpszExtname = p + 1; memcpy((LPSTR)m_lpszTitlename,m_lpszFilename,p - m_lpszFilename); return m_lpszTitlename; } p --; } strcpy((LPSTR)m_lpszTitlename,m_lpszFilename); } return (LPCTSTR)m_lpszTitlename; } /////////////////////////////////////////////////////////////////////////////////////// // BOOL ringFile::isExist(LPCTSTR lpPathFilename) { if(lpPathFilename == NULL) return (check() < RFA_NOTEXIST); else return (GetFileAttributes(lpPathFilename) != 0xffffffff); } BOOL ringFile::isFile(LPCTSTR lpPathFilename) { if(lpPathFilename == NULL) return (m_aAttrib == RFA_FILE); else { DWORD attr = GetFileAttributes(lpPathFilename); if((attr == 0xffffffff) || (attr & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY) return FALSE; else return TRUE; } } BOOL ringFile::copyTo(LPCTSTR lpNewName,BOOL bForceOverWrite) { if(lpNewName == NULL || *lpNewName == '\0') return FALSE; if(m_bExtern) { LPSTR lpbuf; int cnt = ReadAll(&lpbuf); if(cnt > 0) { ringFile rf = lpNewName; if(rf.isExist() && !bForceOverWrite) return FALSE; if(rf.Create(RF_NEW)) { if(rf.Write(lpbuf,cnt)) return TRUE; else return FALSE; } } return FALSE; } char dbuf[MAX_PATH]; DWORD attr = GetAttrib(); if((attr & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY) { if(lpNewName[strlen(lpNewName)-1] == '\\') wsprintf(dbuf,"%s%s\0\0",lpNewName,Filename()); else wsprintf(dbuf,"%s\\%s\0\0",lpNewName,Filename()); } else strcpy((char*)dbuf, (const char *)lpNewName); // 拷贝文件 return ::CopyFile(m_szFilename,dbuf,!bForceOverWrite); } BOOL ringFile::delIt() { if(m_bExtern) return FALSE; Close(); return DeleteFile(m_szFilename); } BOOL ringFile::moveTo(LPCTSTR lpNewName,BOOL bForceOverWrite) { if(m_bExtern || lpNewName == NULL || *lpNewName == '\0') return FALSE; char dbuf[MAX_PATH]; DWORD attr = GetFileAttributes(lpNewName); if((attr & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY) { if(lpNewName[strlen(lpNewName)-1] == '\\') wsprintf(dbuf,"%s%s\0\0",lpNewName,Filename()); else wsprintf(dbuf,"%s\\%s\0\0",lpNewName,Filename()); } else strcpy(dbuf,lpNewName); DWORD how = bForceOverWrite?MOVEFILE_REPLACE_EXISTING:0; DWORD loc = 0UL; BOOL bOpened = (BOOL)m_hFile; // 如果文件处于打开状态,则先关闭它 if(m_hFile) { loc = GetRWLocation(); Close(); } // 移动文件 BOOL bOK; if(OSType() == OST_WINNT) bOK = ::MoveFileEx(m_szFilename,dbuf,how); else { bOK = copyTo(dbuf,how);//ringFile rf = dbuf; if(bOK) delIt(); } // 如果移动失败,恢复原状态 if(!bOK) { if(bOpened) { Open(RF_READWRITE); Seek(loc); } return FALSE; } // 关联到新的位置 SetFile(dbuf); if(bOpened) { Open(RF_READWRITE); Seek(loc); } return TRUE; } BOOL ringFile::reName(LPCTSTR lpNewName) { if(m_bExtern || lpNewName == NULL || *lpNewName == '\0') return FALSE; char dbuf[MAX_PATH]; char szTemp[MAX_PATH]; strcpy(szTemp,Pathname()); if(szTemp[strlen(szTemp)-1] == '\\') szTemp[strlen(szTemp)-1] = 0; wsprintf(dbuf,"%s\\%s\0\0",szTemp,lpNewName); return moveTo((LPSTR)dbuf,FALSE); } /**************************************************** // //原版本使用GetFileAttributes只能得到FAT的文件信息 //现已修正可适应NTFS // ****************************************************/ DWORD ringFile::GetAttrib(LPCTSTR lpszfilename/*=NULL*/) { LPCTSTR lps = lpszfilename; if(lps == NULL) lps = m_szFilename; WIN32_FILE_ATTRIBUTE_DATA wData; memset(&wData,0,sizeof(WIN32_FILE_ATTRIBUTE_DATA)); if(GetFileAttributesEx(lps,GetFileExInfoStandard,&wData)) return wData.dwFileAttributes; else return m_dwFileAttr; } BOOL ringFile::SetAttrib(DWORD dwFileAttributes) { if(SetFileAttributes(m_szFilename,dwFileAttributes)) { m_dwFileAttr = dwFileAttributes; return TRUE; } return FALSE; } BOOL ringFile::GetFileTime(LPFILETIME lpCreate, LPFILETIME lpLast, LPFILETIME lpModify) { BOOL result; if(m_hFile) result = ::GetFileTime(m_hFile,lpCreate,lpLast,lpModify); else { if(MASK_MATCH(GetAttrib(),FILE_ATTRIBUTE_DIRECTORY)) result = Open(RF_READ,RF_SHARE_READ,FILE_FLAG_BACKUP_SEMANTICS); else result = Open(); if(result) result = ::GetFileTime(m_hFile,lpCreate,lpLast,lpModify); Close(); } return result; } //如果文件已打开且以只读方式打开,失败 BOOL ringFile::SetFileTime(LPFILETIME lpCreate, LPFILETIME lpLast, LPFILETIME lpModify) { BOOL bOpen = FALSE; if(!m_hFile) { if(MASK_MATCH(GetAttrib(),FILE_ATTRIBUTE_DIRECTORY)) bOpen = Create(RF_EDIT,FILE_FLAG_BACKUP_SEMANTICS); else bOpen = Create(RF_EDIT); } // 设置时间 BOOL result = ::SetFileTime(m_hFile,lpCreate,lpLast,lpModify); if(bOpen) Close(); return result; } ////////////////////////////////////////////////////////////////////////////////////// // BOOL ringFile::SelectDir(LPTSTR lpDir,LPCTSTR lpszTitle/*="选择路径"*/, UINT uFlag/*=BIF_RETURNONLYFSDIRS*/,BFFCALLBACK lpfn/*=NULL*/, LPARAM lParam/*=0*/,int iImage/*=0*/) { return ::SelectDir(lpDir,lpszTitle,uFlag,lpfn,lParam,iImage); } BOOL ringFile::mdir(LPCTSTR szPath) { return ::MkDir(szPath); } HINSTANCE ringFile::exec(LPCTSTR lpFile,LPCTSTR lpDir/*=NULL*/,LPCTSTR lpParam/*=NULL*/,LPCTSTR lpOp/*=NULL*/,INT nShowCmd/*=SW_SHOW*/) { return ::ringExec(lpFile, lpDir, lpParam, lpOp, nShowCmd); } /* //检查文件名合法性 BOOL ringFile::isValidName() { char buf[MAX_PATH]; int i; // 检查驱动器标识的合法性 if(strlen(m_szDrive) > 0) { char *p, drv=m_szDrive[0]; DWORD dwlog; if (m_szDrive[1] != ':') { return FALSE; } // 获取逻辑驱动器名称串 dwlog = ::GetLogicalDriveStrings(_RFMAX_PATH, (LPSTR)buf); //assert(dwlog); // 连成一个单串 for (i=3; i<(int)dwlog; i+=4) { buf[i] = ' '; } strlwr((char*)buf); drv = (char)tolower(drv); p = (char*)buf; // 检查该驱动器标识符是否合法 while ((*p != drv)&&(*p != '\0')) { p += 4; } if (*p == 0) { return FALSE; } //assert(*p == drv); } strcpy((char*)buf, m_lpszPath); strcat((char*)buf, m_lpszFilename); int len = strlen(buf); LPTSTR lpstr = (LPTSTR)buf; // 如果不存在路径和文件名,则直接返回 if (len == 0) { return TRUE; } for(i=0; i<len; i++) { if(*lpstr == ':' || *lpstr == '*' || *lpstr == '?' || *lpstr == '\"' || *lpstr == '<' || *lpstr == '>' || *lpstr == '|') { return FALSE; } else if(is_dir_sep((TCHAR)(*lpstr))) { lpstr++; if(is_dir_sep((TCHAR)(*lpstr))) { return FALSE; } else { continue; } } lpstr++; } return TRUE; } */ unsigned __int64 ringFile::GetDiskFreeSize(LPSTR lpRoot) { DWORD sect, numbytes, free, clusters; if (::GetDiskFreeSpace(lpRoot, §, &numbytes, &free, &clusters) == 0) { return (__int64)0; } return (unsigned __int64)sect*(unsigned __int64)free*(unsigned __int64)numbytes; } //检查文件是否存在及属性 int ringFile::check() { // 获取文件属性 m_dwFileAttr = GetFileAttributes(m_szFilename); if(m_dwFileAttr != 0xffffffff) { if((m_dwFileAttr&FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY) return RFA_PATH; else return RFA_FILE; } else return RFA_NOTEXIST; } /* void ringFile::SplitFilename() { // 解析路径及文件名 _splitpath((const char *)m_szFilename, m_szDrive, m_lpszPath, m_lpszTitlename, m_lpszExtname); int lene = strlen((const char *)m_lpszExtname); if (lene == 1) { *m_lpszExtname = '\0'; } // 复制+拼合 strcpy((char*)m_lpszFilename, (const char *)m_lpszTitlename); strcat((char*)m_lpszFilename, (const char *)m_lpszExtname); if (lene > 1) { memmove((void*)m_lpszExtname, (const void *)&m_lpszExtname[1], lene); } } */ /////////////////////////////////////////////////////////////////////////////////////// // 异步文件类 ringAsynFile::ringAsynFile() { m_hFile = NULL; m_dwLoFileSize = 0UL; m_dwHiFileSize = 0UL; m_dwTrue = 0UL; m_OSType = ::OSType(); } ringAsynFile::~ringAsynFile() { if (m_hFile) { ::CloseHandle(m_hFile); } } BOOL ringAsynFile::Create(LPCSTR lpFilename) { //assert(m_hFile == NULL); //assert(lpFilename); DWORD att = FILE_ATTRIBUTE_NORMAL|FILE_FLAG_RANDOM_ACCESS|((m_OSType==NT)? FILE_FLAG_OVERLAPPED:0); ::SetLastError(ERROR_SUCCESS); // 创建异步文件(同名文件将被销毁) m_hFile = ::CreateFile(lpFilename, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_ALWAYS|TRUNCATE_EXISTING, att, NULL); if (m_hFile == INVALID_HANDLE_VALUE) { m_hFile = NULL; return FALSE; // 创建文件失败 } m_dwLoFileSize = m_dwHiFileSize = 0UL; // 刚创建的文件尺寸为0字节 return TRUE; } BOOL ringAsynFile::Open(LPCSTR lpFilename) { //assert(m_hFile == NULL); //assert(lpFilename); DWORD att = FILE_ATTRIBUTE_NORMAL|FILE_FLAG_RANDOM_ACCESS|((m_OSType==NT)? FILE_FLAG_OVERLAPPED:0); ::SetLastError(ERROR_SUCCESS); // 打开异步文件 m_hFile = ::CreateFile(lpFilename, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, att, NULL); if (m_hFile == INVALID_HANDLE_VALUE) { m_hFile = NULL; return FALSE; // 打开文件失败(或指定文件不存在) } m_dwLoFileSize = ::GetFileSize(m_hFile, &m_dwHiFileSize); return TRUE; } void ringAsynFile::Close() { //assert(m_hFile); ::CloseHandle(m_hFile); m_hFile = NULL; m_dwLoFileSize = m_dwHiFileSize = 0UL; } int ringAsynFile::Read(LPVOID lpBuf,DWORD dwNum,DWORD offset) { //assert(m_hFile&&lpBuf&&dwNum); if (m_OSType == NT) { // 等待,直到上一个异步操作完成(以让出OVERLAPPED结构空间) ::WaitForSingleObject(m_hFile, INFINITE); memset((void*)&m_sOverLapped, 0, sizeof(OVERLAPPED)); m_sOverLapped.Offset = offset; } ::SetLastError(ERROR_SUCCESS); // 读数据 if (::ReadFile(m_hFile, lpBuf, dwNum, &m_dwTrue, (m_OSType==NT) ? &m_sOverLapped:NULL)) { return 1; // 文件数据已经读出 } else { if (::GetLastError() == ERROR_IO_PENDING) { return 0; // 操作系统开始准备异步读取 } else { return -1; // ReadFile()函数执行失败 } } } int ringAsynFile::Write(const LPVOID lpBuf,DWORD dwNum,DWORD offset) { //assert(m_hFile&&lpBuf&&dwNum); if (m_OSType == NT) { // 等待上一个异步操作完成 ::WaitForSingleObject(m_hFile, INFINITE); memset((void*)&m_sOverLapped, 0, sizeof(OVERLAPPED)); m_sOverLapped.Offset = offset; } ::SetLastError(ERROR_SUCCESS); // 写数据 if (::WriteFile(m_hFile, lpBuf, dwNum, &m_dwTrue, (m_OSType==NT) ? &m_sOverLapped:NULL)) { return 1; // 数据已写入文件 } else { if (::GetLastError() == ERROR_IO_PENDING) { return 0; // 操作系统开始准备异步写入 } else { return -1; // WriteFile()函数执行失败 } } } BOOL ringAsynFile::ConfirmOver(BOOL wait) { //assert(m_hFile); if (m_OSType == NT) { if (::WaitForSingleObject(m_hFile, (wait)?INFINITE:0) == WAIT_OBJECT_0) { return TRUE; // 异步操作完成 } else { return FALSE; } } else { return TRUE; } } BOOL ringAsynFile::QuestionResult(LPDWORD dwRWTure, LPDWORD errCode) { //assert(m_hFile); BOOL rc; if (m_OSType == NT) { // 获取操作结果(如果异步操作还没有已完成,否则控制将被阻塞在这) rc = ::GetOverlappedResult(m_hFile, &m_sOverLapped, &m_dwTrue, TRUE); } else { rc = (::GetLastError() == ERROR_SUCCESS) ? TRUE : FALSE; } if (dwRWTure) { *dwRWTure = m_dwTrue; } if (errCode) { *errCode = ::GetLastError(); } return rc; // TRUE-读写操作成功完成,FALSE-操作失败 } DWORD ringAsynFile::GetFileLength() { //assert(m_hFile); ::SetLastError(ERROR_SUCCESS); return m_dwLoFileSize; } ////////////////////////////////////////////////////////// // //内存映像文件 // ////////////////////////////////////////////////////////// ringMappingFile::~ringMappingFile() { if(m_hMapping) CloseHandle(m_hMapping); } HANDLE ringMappingFile::CreateMapping(DWORD dwProtectFlag,DWORD dwMaxSizeLow, DWORD dwMaxSizeHigh,LPCTSTR lpName) { HANDLE hMap = NULL; if(m_hFile && Size() > 0) { hMap = CreateFileMapping(m_hFile,NULL,dwProtectFlag,dwMaxSizeHigh,dwMaxSizeLow,lpName); if(m_hMapping == NULL) m_hMapping = hMap; } return hMap; } LPBYTE ringMappingFile::CreateView(DWORD dwAccess,DWORD dwNumber,HANDLE hMap, DWORD dwOffsetLow,DWORD dwOffsetHigh) { if(hMap == NULL) hMap = m_hMapping; if(hMap) return (LPBYTE)MapViewOfFile(hMap,dwAccess,dwOffsetHigh,dwOffsetLow,dwNumber); else return NULL; } BOOL ringMappingFile::DeleteView(LPVOID lpv) { return UnmapViewOfFile(lpv); } BOOL ringMappingFile::UnMap(HANDLE hMap) { if(hMap == NULL) hMap = m_hMapping; BOOL bOK = CloseHandle(hMap); if(hMap == m_hMapping) m_hMapping = NULL; return bOK; }